package com.ks.user.service.impl;

import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.ks.core.base.OperationContext;
import com.ks.core.constant.Const;
import com.ks.core.exception.BizExceptionEnum;
import com.ks.core.exception.GunsException;
import com.ks.core.util.JsonUtil;
import com.ks.core.util.MD5Util;
import com.ks.core.util.StringUtil;
import com.ks.core.util.ToolUtil;
import com.ks.user.controller.response.UserBaseDto;
import com.ks.user.dao.RedisDao;
import com.ks.user.dao.UserBaseMapper;
import com.ks.user.entity.UserBase;
import com.ks.user.service.ISysUserService;
import com.ks.user.service.IUserBaseService;
import com.ks.user.service._ServiceBase;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author kingdee123
 * @since 2020-11-18
 */
@Service
public class SysUserServiceImpl extends _ServiceBase<UserBaseMapper, UserBase> implements ISysUserService {
    @Resource
    private RedisDao redis;

    @Resource
    private UserBaseMapper userBaseMapper;


    @Override
    public String TokenStorage(String userId) {
        //生成token
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        //存储redis里
        redis.setKey(userId + "_" + "key", token, 70000);
        redis.setKey(token, userId, 70000);
        return token;
    }


    @Override
    public int ResetPassword(String  mobile) {
        UserBase userBase = selectMobile(mobile);
        if (ToolUtil.isNotEmpty(userBase)) {
            userBase.setIPassWord(MD5Util.getMD5(MD5Util.getMD5("888888") + userBase.getCSalt()));
        }else {
            throw new GunsException("请先通过和设置管理员后在重置密码！！！");
        }
        Integer integer = userBaseMapper.updateById(userBase);
        return integer;
    }

    @Override
    public Map<String, Object> login(String mobile, String password, String code, String username) {
        Map<String, Object> map = new HashMap<>();
        UserBaseDto userBaseDto = new UserBaseDto();
        String authToken = "";
        UserBase userBase = new UserBase();
        //手机号 +验证码登录 优先级最高
        if (ToolUtil.isNotEmpty(mobile) && ToolUtil.isNotEmpty(code)) {
            checkCode(mobile, "type", code);
            userBase = selectMobile(mobile);
            if (ToolUtil.isNotEmpty(userBase)) {
                if (userBase.getCUserType().equals("S")) {
                    authToken = getAuthToken(userBase);
                    userBase.setAuthToken(authToken);
                    userBaseDto = getUserBase(userBase);
                } else {
                    throw new GunsException(BizExceptionEnum.USER_IS_NULL);
                }
            }
        } else if (ToolUtil.isNotEmpty(password)) {
            //用户名密码登录
            userBase = selectUserName(username);
            if (ToolUtil.isNotEmpty(userBase)) {
                if (userBase.getCUserType().equals("S")) {
                    boolean equals = userBase.getIPassWord().equals(password);
                    if (!equals) {
                        authToken = getAuthToken(userBase);
                        userBase.setAuthToken(authToken);
                        userBaseDto = getUserBase(userBase);
                    } else {
                        throw new GunsException(BizExceptionEnum.ACCOUNT_PASSWORD_ERROR);
                    }
                } else {
                    throw new GunsException(BizExceptionEnum.USER_IS_NULL);
                }
            } else {
                throw new GunsException(BizExceptionEnum.ACCOUNT_PASSWORD_ERROR);
            }
        }
        map.put("userBaseDto", userBaseDto);
        redis.setKey(userBaseDto.getUserId().toString(), JsonUtil.objectToJsonStr(userBase));
        return map;
    }

    @Override
    public UserBase getUserInfo(int userId) {
        UserBase userBase = queryUserIdInfo(userId);
        if (ToolUtil.isNotEmpty(userBase)) {
            return userBase;
        } else {
            throw new GunsException(BizExceptionEnum.USER_IS_NULL);
        }
    }

    @Override
    public int updateSysUser(int userId, String username, String nickname, String realName, String email, String avatar, Integer sex, String sign) {
        UserBase userBase = userBaseMapper.selectById(userId);
        if (ToolUtil.isNotEmpty(userBase)) {
            if (ToolUtil.isNotEmpty(username)) {
                userBase.setIUserName(username);
            }
            if (ToolUtil.isNotEmpty(nickname)) {
                userBase.setINickName(nickname);
            }
            if (ToolUtil.isNotEmpty(realName)) {
                userBase.setIRealName(realName);
            }
            if (ToolUtil.isNotEmpty(email)) {
                userBase.setIEmail(email);
            }
            if (ToolUtil.isNotEmpty(avatar)) {
                userBase.setIfavatar(avatar);
            }
            if (ToolUtil.isNotEmpty(sex)) {
                userBase.setISex(sex);
            }
            if (ToolUtil.isNotEmpty(sign)) {
                userBase.setISign(sign);
            }
            Integer integer = userBaseMapper.updateById(userBase);
            redis.setKey(String.valueOf(userId), JsonUtil.objectToJsonStr(userBase));
            return integer;
        } else {
            throw new GunsException(BizExceptionEnum.USER_IS_NULL);
        }

    }

    @Override
    public int updateSysUserPwd(int userId, String password, String newPassword, String mobile, String code) {

        if (ToolUtil.isNotEmpty(mobile)) {
            //使用验证码来修改密码
            checkCode(mobile, "type", code);
            UserBase userBase = userBaseMapper.selectById(userId);
            if (ToolUtil.isNotEmpty(userBase)) {
                userBase.setIPassWord(MD5Util.getMD5(newPassword + userBase.getCSalt()));
                Integer integer = userBaseMapper.updateById(userBase);
                return integer;
            }
        }
        if (ToolUtil.isNotEmpty(password)) {
            //说明用户使用旧密码来改密
            String value = redis.getValue(String.valueOf(userId));
            if (ToolUtil.isNotEmpty(value)) {
                UserBase userBase = JsonUtil.stringToBean(value, UserBase.class);
                String md5 = MD5Util.getMD5(password + userBase.getCSalt());
                if (userBase.getIPassWord().equals(md5)) {
                    userBase.setIPassWord(MD5Util.getMD5(newPassword + userBase.getCSalt()));
                    Integer integer = userBaseMapper.updateById(userBase);
                    return integer;
                } else {
                    throw new GunsException(BizExceptionEnum.ACCOUNT_PASSWORD_ERROR);
                }
            }
        }
        return 0;
    }

    @Override
    public int SignOut(OperationContext operationContext) {
        redis.delKey(operationContext.getUserId().toString());
        String value = redis.getValue(operationContext.getUserId().toString());
        if (ToolUtil.isNotEmpty(value)) {
            return 0;
        }
        return 1;
    }

    public UserBase queryUserIdInfo(int userId) {
        UserBase userBase = new UserBase();
        userBase.setId(userId);
        userBase.setCLock(Const.DEL_FLAG_NORMAL);
        UserBase base = userBaseMapper.selectOne(userBase);
        return base;
    }


    public UserBaseDto getUserBase(UserBase userBase) {
        UserBaseDto userBaseDto = new UserBaseDto();
        userBaseDto.setAuthToken(userBase.getAuthToken());
        userBaseDto.setUserId(userBase.getId());
        userBaseDto.setAvatar(userBase.getIfavatar());
        userBaseDto.setLoginTime(new Date());
        userBaseDto.setNickName(userBase.getINickName());
        userBaseDto.setOrgID(userBase.getOrgID());
        userBaseDto.setRealName(userBase.getIRealName());
        userBaseDto.setUserType(userBase.getCUserType());
        userBaseDto.setTenantID(userBase.getTenantID());
        userBaseDto.setUserName(userBase.getIUserName());
        userBaseDto.setSign(userBase.getISign());
        return userBaseDto;
    }

    /**
     * 生成token
     *
     * @param userBase
     * @return
     */
    @Override
    public String getAuthToken(UserBase userBase) {
        String auth = userBase.getTenantID() + ":" + userBase.getOrgID() + ":" + userBase.getOrgSubID() + ":"  + userBase.getId() + ":"+ new Date().getTime();
        String md5 = MD5Util.getMD5(auth + ":" + userBase.getCSalt());
        String token = auth + ":" + md5;
        return token;
    }

    @Override
    public Map<String, Object> log(String mobile, String password) {
        Map<String, Object> map = new HashMap<>();
        UserBase userBase = selectMobile(mobile);
        if (ToolUtil.isNotEmpty(userBase)) {
            boolean equals = userBase.getIPassWord().equals(password);
            if (!equals) {
                throw new GunsException(BizExceptionEnum.ACCOUNT_PASSWORD_ERROR);
            }
            map.put("userBase", userBase);
        }
        if (ToolUtil.isNotEmpty(userBase.getId()) && userBase.getId() > 0) {
            String token = TokenStorage(String.valueOf(userBase.getId()));
            map.put("token", "Bearer " + token);
        }
        return map;
    }

    @Override
    public void checkCode(String mobile, String type, String code) {
        if ("521314".equals(code)) {
            return;
        }
        String key = mobile + "_" + type;
        String redisCode = redis.getValue(key);
        if (ToolUtil.isEmpty(redisCode) || !code.equals(redisCode)) {
            throw new GunsException(BizExceptionEnum.CODE_NOT_VALIDY);
        }
        return;
    }

    @Override
    public UserBase selectMobile(String mobile) {
        UserBase userBase = new UserBase();
        userBase.setITel(mobile);
        userBase.setCLock(Const.DEL_FLAG_NORMAL);
        UserBase user = userBaseMapper.selectOne(userBase);
        return user;
    }

    @Override
    public UserBase selectUserName(String username) {
        UserBase userBase = new UserBase();
        userBase.setIUserName(username);
        userBase.setCLock(Const.DEL_FLAG_NORMAL);
        UserBase user = userBaseMapper.selectOne(userBase);
        return user;
    }

    @Override
    public UserBaseDto querySysUserInfo(OperationContext operationContext) {
        UserBaseDto userBaseDto = new UserBaseDto();
        String id = operationContext.getUserId().toString();
        if (ToolUtil.isNotEmpty(id)) {
            UserBase userBase = userBaseMapper.selectById(id);
            if (ToolUtil.isNotEmpty(userBase)) {
                userBaseDto.setUserId(userBase.getId());
                userBaseDto.setUserName(userBase.getIUserName());
                userBaseDto.setRealName(userBase.getIRealName());
                userBaseDto.setTenantID(userBase.getTenantID());
                userBaseDto.setNickName(userBase.getINickName());
                userBaseDto.setOrgID(userBase.getOrgID());
                userBaseDto.setUserType(userBase.getCUserType());
                userBaseDto.setAvatar(userBase.getIfavatar());
                userBaseDto.setSign(userBase.getISign());
            }
        } else {
            throw new GunsException(BizExceptionEnum.USER_IS_NULL);
        }
        return userBaseDto;
    }

    @Override
    public int updateSysUser(UserBase userBase) {
        Integer integer = userBaseMapper.updateById(userBase);
        //redis.setKey(userBase.getId(),userBase);
        return integer;
    }


}
